package com.clss.uvctest.webrtcController

import android.annotation.SuppressLint
import com.clss.uvctest.Constant
import com.clss.uvctest.SpHelper
import com.clss.uvctest.stompNew.Stomp
import com.clss.uvctest.stompNew.StompClient
import com.clss.uvctest.stompNew.dto.LifecycleEvent
import com.clss.webrtclibrary.Lg
import com.clss.webrtclibrary.KurentoSignActionType
import com.clss.webrtclibrary.KurentoSignallingBean
import com.clss.webrtclibrary.MediaInfoBean
import com.clss.uvctest.webrtcController.WebRtcSignListener
import com.google.gson.Gson
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.apache.commons.text.StringEscapeUtils
import org.json.JSONObject
import java.util.*

class WebRtcSignController (
    webRtcSignListener: WebRtcSignListener,
    mediaInfoBean: MediaInfoBean
){

    private val TAG = "WebRtcSignController"
    private val XMPP = "xmpp"
    private val STOMP = "stomp"
    private val SIGNALING = "SIGNALING"
    private val ROOM = "room"
    private val PLAYER = "player"

    private var mStompClient : StompClient? = null
    private var mMediaInfoBean : MediaInfoBean? = null
    private var mWebRtcSignListener : WebRtcSignListener? = null
    private val mGson = Gson()
    private var isStompConnected = false
    private var isStompLine = true
    private var mSignType = ROOM
    private var isStarted = false
    private var mPlayerId = ""

    init {
        mWebRtcSignListener = webRtcSignListener
        mMediaInfoBean = mediaInfoBean
//        mMediaInfoBean?.signalingBean?.protocolFlag = XMPP
//        mXmppBinder = xmppBinder
//        isStompLine = mMediaInfoBean?.signalingBean?.protocolFlag == STOMP

        Lg.i(TAG, "---isStompLine===" + isStompLine)
        Lg.i(TAG, "---mMediaInfoBean?.id===" + mMediaInfoBean?.id)
        Lg.i(TAG, "---currentTimeMillis===" + Date())
    }

    /** WebRtc可以开始工作了 */
    fun signLineStartWork(){
        if (isStompLine){
            createStompConnection()
        }else {
            startXmppSendSign()
        }
    }

    /** 关闭信道 */
    fun disconnectionSignLine(){
        Lg.i(TAG, "---disconnectionSignLine===")
        android.os.Handler().postDelayed({
            mStompClient?.disconnect()
            mStompClient = null
        }, 2 * 1000)
    }

    /** stomp传递信令的方法 */
    private fun createStompConnection(){
        Lg.i(TAG, "---createStompConnection===" + mMediaInfoBean.toString())

        val headerMap = mapOf(Constant.APP_TOKEN to SpHelper.getInstance().token)
        mStompClient = Stomp.over(mMediaInfoBean?.signalingBean?.stompHost, headerMap)
        mStompClient?.withClientHeartbeat(0)?.withServerHeartbeat(2000)
        stompLifecycle()
        stompTopic()
        mStompClient?.connect()
    }

    @SuppressLint("CheckResult")
    private fun stompTopic(){
        Lg.i(TAG, "---stompTopic===")
        mStompClient?.topic("/queue/SIGNALING_" + SpHelper.getInstance().userId)
                ?.subscribeOn(Schedulers.io())
                ?.observeOn(AndroidSchedulers.mainThread())
                ?.subscribe ({ topicMessage ->
                    Lg.i(TAG, "---Received===" + topicMessage.payload)

                    //TODO 收到新的信令消息
                    val body = JSONObject(topicMessage.payload).get("body").toString()
                    hasRemoteSignMessage(body)
                }, { t -> Lg.e(TAG, "---topic===$t") })
    }

    @SuppressLint("CheckResult")
    private fun stompLifecycle(){
        Lg.i(TAG, "---stompLifecycle===")
        mStompClient?.lifecycle()
                ?.subscribeOn(Schedulers.io())
                ?.observeOn(AndroidSchedulers.mainThread())
                ?.subscribe({ t ->
                    when (t?.type) {
                        LifecycleEvent.Type.OPENED -> {
                            Lg.e(TAG, "---OPENED===")
                            //TODO 连接开启
                            isStompConnected = true
                            mWebRtcSignListener?.signLineIsOpened()

                        }
                        LifecycleEvent.Type.CLOSED -> {
                            Lg.e(TAG, "---CLOSED===")
                            //TODO 连接关闭
                            isStompConnected = false
                            mWebRtcSignListener?.signLineIsClosed()
                        }
                        LifecycleEvent.Type.ERROR -> {
                            Lg.e(TAG, "---ERROR===")
                            //TODO 连接报错
                        }
                        LifecycleEvent.Type.FAILED_SERVER_HEARTBEAT -> {
                            Lg.e(TAG, "---FAILED_SERVER_HEARTBEAT===")

                        }
                    }
                },
                        { t -> Lg.e(TAG, "---lifecycle===$t") })
    }
    /** 收到了远端的信令 */
    fun hasRemoteSignMessage(remoteSign : String){

        Lg.i(TAG, "---hasRemoteSignMessage===" + remoteSign)
        val unescapeJson = StringEscapeUtils.unescapeJson(remoteSign)
        val receiveMsg = mGson.fromJson(unescapeJson, KurentoSignallingBean::class.java)
        Lg.i(TAG, "---receiveMsg.room===" + receiveMsg.room + "---mMediaInfoBean?.id===" + mMediaInfoBean?.id)
//        if (!receiveMsg.room.equals(mMediaInfoBean?.id)){
//            return
//        }
        if (receiveMsg.id.equals(KurentoSignActionType.leaveRoomAnswer.name) ||
                receiveMsg.id.equals(KurentoSignActionType.joinRoomAnswer.name)){
            isStarted = true
        }
        if (receiveMsg.id.equals(KurentoSignActionType.createResponse.name)){
            isStarted = true
            mPlayerId = receiveMsg.player
        }
        if (mSignType.equals(ROOM)) {
            if (!mMediaInfoBean?.id.equals(receiveMsg.room)) {
                Lg.i(TAG, "---it's not current room===")
                return
            }
        }else if (mSignType.equals(PLAYER)){
            if (!mPlayerId.equals(receiveMsg.player)){
                Lg.i(TAG, "---it's not current Player===")
                return
            }
        }
        if (isStarted) {
            mWebRtcSignListener?.hasRemoteSignInfo(receiveMsg)
        }
    }

    @SuppressLint("CheckResult")
    fun hasLocalSignMessagge(sign : KurentoSignallingBean){
        Lg.i(TAG, "---hasLocalSignMessagge===" + sign.toString())
        if (sign.id.equals(KurentoSignActionType.create.name)){
            mSignType = PLAYER
        }
        if (isStompLine) {
            mStompClient?.send(
                    "/app/signaling.$mSignType.${mMediaInfoBean?.signalingBean?.stompDestination}",
                    mGson.toJson(sign))
                    ?.subscribeOn(Schedulers.io())
                    ?.observeOn(Schedulers.io())
                    ?.subscribe({
                        Lg.i(TAG, "---发送成功===")
                    },
                            { t -> Lg.e(TAG, "---send===$t") })
        }
    }

//    fun isStompConnected(): Boolean {
//        return isStompConnected
//    }

    /** xmpp通道传递信令的方法 */
    private fun startXmppSendSign(){
        Lg.i(TAG, "---startXmppSendSign===")
        mWebRtcSignListener?.signLineIsOpened()
    }
}
